home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-09-28 | 8.7 KB | 405 lines | [TEXT/CWIE] |
- /*
- File: MoreTextUtils.cp
-
- Contains:
-
- Written by: Pete Gontier
-
- Copyright: Copyright (c) 1998 Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
-
- <6> 20/3/00 Quinn Added MoreReplaceText and its support routines. Added
- MoreStrLen. Tidied up a little.
- <5> 1/3/00 Quinn Minor Carbonation changes.
- <4> 21/4/99 Quinn Added ValidStringListHandle.
- <3> 2/15/99 PCG InlineGetHandleSize loses the Inline
- <2> 11/11/98 PCG fix header
- <1> 11/10/98 PCG first big re-org at behest of Quinn
-
- Old Change History (most recent first):
-
- <2> 10/23/98 PCG add GetStringFromLongDouble
- <1> 6/16/98 PCG initial checkin
- */
-
- /////////////////////////////////////////////////////////////////
-
- // MoreIsBetter Setup
-
- #include "MoreSetup.h"
-
- // Our Prototypes
-
- #include "MoreTextUtils.h"
-
- // Mac OS Interfaces
-
- #include <Resources.h>
- #include <PLStringFuncs.h>
- #include <Fonts.h>
-
- // MIB Prototypes
-
- #include "MoreMemory.h"
- #include "MoreQuickDraw.h"
-
- /////////////////////////////////////////////////////////////////
-
- pascal OSErr NewStringPtr (ConstStr255Param init, UInt8 maxSize, StringPtr *result)
- {
- OSErr err = noErr;
-
- if (!MoreAssert (result && (!init || (*init <= maxSize))))
- err = paramErr;
- else
- {
- *result = StringPtr (NewPtr (1 + (maxSize ? maxSize : (init ? *init : 255))));
-
- if (!*result)
- err = MemError ( );
- else if (init && *init)
- PLstrcpy (*result,init);
- else
- **result = 0;
- }
-
- return err;
- }
-
- pascal OSErr NewStringListHandle (Handle *h)
- {
- DebugStr ("\pThis routine has never been traced.");
-
- if (!MoreAssert (h))
- return nilHandleErr;
- *h = NewHandleClear (sizeof (UInt16));
- if (!*h)
- return MemError ( );
- return noErr;
- }
-
- pascal OSErr AppendStringToListHandle (ConstStr255Param str, Handle h)
- {
- DebugStr ("\pThis routine has never been traced.");
-
- OSErr err = noErr;
-
- if (!MoreAssert (h && *h))
- err = nilHandleErr;
- else
- {
- UInt8 dummyZero;
-
- if (!str)
- {
- dummyZero = 0;
- str = &dummyZero;
- }
-
- if (!(err = PtrAndHand (str, h, *str + 1)))
- (** (UInt16 **) h) += 1;
- }
-
- return err;
- }
-
- pascal OSErr GetNewStringList (short resID, tStringListP *newStringList)
- {
- OSErr err = noErr;
-
- Handle h = GetResource ('STR#',resID);
-
- if (!h)
- {
- err = ResError ( );
- if (!err) err = resNotFound;
- }
- else
- {
- Size handleSize = GetHandleSize (h);
- (void) MoreAssert (MemError ( ) == noErr);
-
- if (handleSize < 2)
- err = paramErr;
- else
- {
- UInt16 stringCount = ** (UInt16 **) h;
- Size stringListSize = sizeof (**newStringList) + (handleSize - 2) +
- (stringCount * sizeof (StringPtr));
-
- *newStringList = (tStringListP) NewPtr (stringListSize);
-
- if (!*newStringList)
- err = MemError ( );
- else
- {
- (*newStringList)->count = stringCount;
-
- if (stringCount)
- {
- UInt16 index = 0;
-
- StringPtr stringScan = (StringPtr) ((*newStringList)->list + stringCount);
-
- BlockMoveData (2 + *h, stringScan, handleSize - 2);
-
- do
- {
- (*newStringList)->list [index] = stringScan;
- stringScan += *stringScan + 1;
- }
- while (++index < stringCount);
- }
- }
- }
-
- ReleaseResource (h);
- (void) MoreAssert (ResError ( ) == noErr);
- }
-
- return err;
- }
-
- pascal Boolean ValidStringListHandle(Handle stringList)
- // See comment in interface part.
- {
- Boolean result;
- UInt16 stringCount;
- UInt16 stringIndex;
- UInt8* cursor;
- UInt8* bound;
- ByteCount stringListLength;
-
- result = true;
- if (stringList == NULL || *stringList == NULL || GetHandleSize(stringList) < sizeof(UInt16) ) {
- result = false;
- }
- if (result) {
- stringCount = *((UInt16 *) *stringList);
-
- stringListLength = GetHandleSize(stringList);
-
- // From here down we have to make sure we do nothing to move
- // or purge until we're done with cursor and bound.
-
- cursor = ((UInt8 *)*stringList) + sizeof(UInt16);
- bound = ((UInt8 *)*stringList) + stringListLength;
- for (stringIndex = 0; stringIndex < stringCount; stringIndex++) {
- if ( cursor < bound ) {
- cursor += *cursor + 1;
- } else {
- result = false;
- break;
- }
- }
-
- if (result) {
- if ( cursor != bound ) {
- result = false;
- }
- }
- }
-
- return result;
- }
-
- pascal OSErr GetPascalStringFromLongDouble (long double d, SInt8 precision, StringPtr buf)
- {
- OSErr err = noErr;
-
- *buf = 0;
-
- // If client requests more precision than is available, bitch.
-
- if (!MoreAssert (precision < SIGDIGLEN))
- err = paramErr;
- else
- {
- // If precision is less than 0, client is requesting
- // as much precision as is available.
-
- if (precision < 0)
- precision = SIGDIGLEN;
-
- // Try normal notation, and if that overflows,
- // fall back to scientific notation (bleah!).
-
- decimal dec;
- decform df = { 1, 0, precision };
-
- num2dec (&df,d,&dec);
-
- if (dec.sig.text [0] == '?')
- {
- df.style = 0;
- df.digits = SIGDIGLEN;
-
- num2dec (&df,d,&dec);
- }
-
- if (*(dec.sig.text) == '0')
- PLstrcpy (buf,"\p0");
- else if (*(dec.sig.text) == 'I')
- PLstrcpy (buf,"\p[INF]");
- else if (*(dec.sig.text) == 'N')
- PLstrcpy (buf,"\p[NaN]");
- else
- {
- // Finally, convert it to a pascal string...
-
- dec2str (&df,&dec,(Ptr)buf);
- CopyCStringToPascal( (char *) buf, buf );
-
- // ...and trim trailing zeroes.
-
- // if (df.style == 1 && dec.exp < 0)
- // while (buf [*buf] == '0')
- // *buf -= 1;
- }
- }
-
- return err;
- }
-
- // gDummyPort is a pointer to a dummy GrafPort whose font is always
- // the system font. By setting thePort to this port, we can then safely
- // call Script Manager that get script information from the current port.
-
- static GrafPtr gDummyPort;
-
- extern pascal OSStatus InitMoreTextUtils(void)
- // See comment in header.
- {
- OSStatus err;
- GrafPtr oldPort;
-
- // Preserve the current port.
-
- GetPort(&oldPort);
-
- // Create gDummyPort.
-
- gDummyPort = (GrafPtr) CreateNewPort();
- err = MoreMemError(gDummyPort);
- if (err == noErr) {
-
- // CreateNewPort, if it follows the semantics of the old
- // OpenPort routine, should set thePort to the new port.
- // This assert ensures that behaviour, because the following
- // call to TextFont relies on it.
-
- #if MORE_DEBUG
- {
- GrafPtr junkPort;
-
- GetPort(&junkPort);
- MoreAssertQ(junkPort == gDummyPort);
- }
- #endif
-
- // Set the dummy port’s font to the system font.
-
- TextFont(systemFont);
- }
-
- SetPort(oldPort);
-
- return err;
- }
-
- extern pascal void TermMoreTextUtils(void)
- // See comment in header.
- {
- if (gDummyPort != nil) {
- DisposePort( (CGrafPtr) gDummyPort);
- gDummyPort = nil;
- }
- }
-
- extern pascal void MoreReplaceText(Str255 baseText, ConstStr255Param substitutionText, ConstStr15Param key)
- // See comment in header.
- {
- OSStatus err;
- GrafPtr oldPort;
- Handle baseTextH;
- Handle substitutionTextH;
- Size newLength;
- UInt8 *tmpKey;
-
- MoreAssertQ(baseText != nil);
- MoreAssertQ(substitutionText != nil);
- MoreAssertQ(key != nil);
- MoreAssertQ(key[0] <= 15);
-
- GetPort(&oldPort);
-
- baseTextH = nil;
- substitutionTextH = nil;
-
- // Copy the strings into handles, call ReplaceText, then
- // copy the result back into baseText (making sure that
- // there is at most 255 bytes in the resulting string).
-
- err = noErr;
- if (gDummyPort == nil) {
- err = InitMoreTextUtils();
- }
- if (err == noErr) {
- SetPort(gDummyPort);
-
- err = PtrToHand(&baseText[1], &baseTextH, baseText[0]);
- }
- if (err == noErr) {
- err = PtrToHand(&substitutionText[1], &substitutionTextH, substitutionText[0]);
- }
- if (err == noErr) {
- tmpKey = (UInt8 *) key;
- err = ReplaceText(baseTextH, substitutionTextH, tmpKey);
- if (err >= 0) {
- newLength = GetHandleSize(baseTextH);
- if (newLength > 255) {
- newLength = 255;
- }
- baseText[0] = newLength;
- BlockMoveData(*baseTextH, &baseText[1], newLength);
- err = noErr;
- }
- }
-
- // Clean up.
-
- if (baseTextH != nil) {
- DisposeHandle(baseTextH);
- MoreAssertQ(MemError() == noErr);
- }
- if (substitutionTextH != nil) {
- DisposeHandle(substitutionTextH);
- MoreAssertQ(MemError() == noErr);
- }
- SetPort(oldPort);
-
- MoreAssert(err == noErr);
- }
-
- extern pascal ByteCount MoreStrLen(const char *str)
- // See comment in header.
- {
- ByteCount result;
-
- result = 0;
- while ( *str != 0 ) {
- result += 1;
- str += 1;
- }
- return result;
- }
-